package edu.washington.cs.workflow.spec4j.example;

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JMenuItem;
import javax.swing.MenuElement;

import org.uispec4j.MenuBar;
import org.uispec4j.MenuItem;
import org.uispec4j.Trigger;
import org.uispec4j.UIComponent;
import org.uispec4j.UISpec4J;
import org.uispec4j.UISpecTestCase;
import org.uispec4j.Window;
import org.uispec4j.finder.ComponentMatcher;
import org.uispec4j.interception.MainClassAdapter;
import org.uispec4j.interception.WindowHandler;
import org.uispec4j.interception.WindowInterceptor;

import edu.washington.cs.workflow.analysis.guistructure.Spec4JUtils;
import edu.washington.cs.workflow.analysis.guistructure.UIActionTracer;
import edu.washington.cs.workflow.analysis.guistructure.UIMenuPos;
import edu.washington.cs.workflow.analysis.guistructure.UIPos;
import edu.washington.cs.workflow.analysis.guistructure.uievents.ButtonEvent;
import edu.washington.cs.workflow.analysis.guistructure.uievents.MenuItemEvent;
import edu.washington.cs.workflow.analysis.guistructure.uievents.TextComponentEvent;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEvent;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEventFactory;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEvent.WINDOW;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEventOutcome;

public class TestCrosswordSage extends UISpecTestCase {

	static {
        UISpec4J.init();
    } 
	
	protected void setUp() throws Exception {
		Class<?> clz = Class.forName("crosswordsage.MainScreen");
	    setAdapter(new MainClassAdapter(clz, new String[0]));
	}
	
	public void testGetWindow() {
		
		getMainWindow();
	}
	
	public void testFindMenu() {
		Window window = getMainWindow();
		
		UIActionTracer.tracer.setDisplayRealtime(false);
		
		findAndFireMenu(window, "File");
		findAndFireMenu(window, "Edit");
		findAndFireMenu(window, "Tools");
		findAndFireMenu(window, "Action");
		findAndFireMenu(window, "Help");
	}
	
	public void testClickNewCrossword() {
		Window window = getMainWindow();
		List<String> path = Arrays.asList("File", "New Crossword");
		MenuItem menuItem = Spec4JUtils.findMenuItem(window, path);
		UIEvent menuEvent = UIEventFactory.createRandomEvent(menuItem, window, UIMenuPos.make(path.toArray(new String[0])));
		if(menuEvent.canFireEvent()) {
			System.out.println(menuEvent);
			WINDOW w = menuEvent.probeWindowInfo();
			System.out.println("  w: " + w);
//			menuEvent.fireEvent();
		}
	}
	
	public void testClickNewCrossword_Modal_dialog() {
		Window window = getMainWindow();
		List<String> path = Arrays.asList("File", "New Crossword");
		MenuItem menuItem = Spec4JUtils.findMenuItem(window, path);
		UIEvent menuEvent = UIEventFactory.createRandomEvent(menuItem, window, UIMenuPos.make(path.toArray(new String[0])));
		if(menuEvent.canFireEvent()) {
			System.out.println(menuEvent);
			WINDOW w = menuEvent.probeWindowInfo();
			System.out.println("  w: " + w);
			
			UIEventOutcome outcome = menuEvent.fireEvent();
			Trigger t = outcome.getTrigger();
			WindowInterceptor.init(t).process(new WindowHandler() {
			    public Trigger process(Window dialog) {
			    	Collection<UIEvent> newAvailabeEvents = Spec4JUtils.allAvailableUIEvents(dialog);
					for(UIEvent e : newAvailabeEvents) {
						System.out.println(" in modal dialog: " + e);
						if(e instanceof TextComponentEvent) {
							((TextComponentEvent)e).textComp.setText("3");
						}
					}
			    	
			      return dialog.getButton("OK").triggerClick();
			    }
			  }).run();
		}
	}
	
	public void testAllActions() {
		Window window = getMainWindow();
		Collection<UIEvent> events = Spec4JUtils.allNonNullRandomUIEvents(window);
		System.out.println(events.size()); 
		for(UIEvent event : events) {
			if(event.canFireEvent()) {
				event.probeWindowInfo();
				event.fireEvent();
//		        System.err.println(event);
			}
		}
	}
	
	private void findAndFireMenu(Window window, String root) {
		MenuItem helpItem = Spec4JUtils.findMenuItem(window, Arrays.asList(root));
		List<List<String>> paths = Spec4JUtils.getAllSubMenuPaths(helpItem);
		for(List<String> path : paths) {
			MenuItem menuItem = Spec4JUtils.findMenuItem(window, path);
			UIEvent menuEvent = UIEventFactory.createRandomEvent(menuItem, window, UIMenuPos.make(path.toArray(new String[0])));
			System.out.println(menuEvent);
			if(menuEvent.canFireEvent()) {
			    System.out.println("    " + menuEvent.probeWindowInfo());
			    System.out.println("    " + menuEvent.fireEvent());
			}
		}
	}
	
	public void testMenu0() {
		Window window = getMainWindow();
//		System.out.println(window.getDescription());
		UIComponent[] uics = window.getUIComponents(ComponentMatcher.ALL);
		for(UIComponent uic : uics) {
			if(uic instanceof MenuItem) {
				MenuItem item = (MenuItem)uic;
				JMenuItem jitem = (JMenuItem)uic.getAwtComponent();
				System.out.println(jitem.getText());
			    List<String> l = Spec4JUtils.getSubMenuText((MenuItem)uic);
			    System.out.println("   " + l);
			    
			    List<List<String>> paths = Spec4JUtils.getAllSubMenuPaths(item);
			    System.out.println(paths);
			}
		}
	}
	
	public void testMenu1() {
		Window window = getMainWindow();
		System.out.println(window.getDescription());
		
		UIComponent[] uics = window.getUIComponents(ComponentMatcher.ALL);
		for(UIComponent uic : uics) {
			if(uic instanceof MenuItem) {
				System.out.println(uic);
				
				MenuItem item = (MenuItem)uic;
				
				JMenuItem jitem = (JMenuItem)item.getAwtComponent();
				System.out.println(jitem.getSubElements().length);
				   MenuElement[] elems = jitem.getSubElements()[0].getSubElements();
				   System.out.println("   " + jitem.getText() + ", class: " + jitem.getClass() + ", sub num: " + jitem.getSubElements().length);
				   System.out.println("   " + jitem.getSubElements()[0]);
//				   System.out.println(item);
				   for(MenuElement ele : elems) {
					   String text = ((JMenuItem)ele.getComponent()).getText();
						System.out.println("        " + text + ",  " + ele.getComponent().getClass());
						if(text.equals("About")) {
							System.out.println("  --- ");
							MenuItem subItem = item.getSubMenu(text);
							System.out.println(((JMenuItem)subItem.getAwtComponent()).getText());
							UIEvent sube = UIEventFactory.createRandomEvent(subItem, window, UIPos.make(1));
							System.out.println(sube.canFireEvent());
							sube.probeWindowInfo();
							UIEventOutcome outcome = sube.fireEvent();
							System.out.println(outcome);
							break;
						}
				   }
			}
		}
	}
}
